package com.mlethe.library.utils;

/**
 * 16进制数据处理工具类
 *
 * @author Mlethe
 */
public class HexDataTool {
    /**
     * 判断奇数或偶数，位运算，最后一位是1则为奇数，为0是偶数
     *
     * @param num
     * @return
     */
    static public int isOdd(int num) {
        return num & 0x1;
    }

    /**
     * Hex字符串转int
     *
     * @param hex
     * @return
     */
    public static int hexToInt(String hex) {
        return Integer.parseInt(hex, 16);
    }

    /**
     * Hex字符串转byte
     *
     * @param hex
     * @return
     */
    public static byte hexToByte(String hex) {
        return (byte) Integer.parseInt(hex, 16);
    }

    /**
     * 1字节转2个Hex字符
     *
     * @param b
     * @return
     */
    public static String byteToHex(Byte b) {
        return String.format("%02x", b).toUpperCase();
    }

    /**
     * 字节数组转转hex字符串
     *
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder strBuilder = new StringBuilder();
        int j = bytes.length;
        for (int i = 0; i < j; i++) {
            strBuilder.append(byteToHex(bytes[i]));
        }
        return strBuilder.toString();
    }

    /**
     * 字节数组转转hex字符串，可选长度
     *
     * @param bytes
     * @param startPoi 开始位置
     * @param endPoi   结束位置
     * @return
     */
    public static String bytesToHex(byte[] bytes, int startPoi, int endPoi) {
        StringBuilder strBuilder = new StringBuilder();
        int j = endPoi;
        for (int i = startPoi; i < j; i++) {
            strBuilder.append(byteToHex(bytes[i]));
        }
        return strBuilder.toString();
    }

    /**
     * 转hex字符串转字节数组
     *
     * @param hexStr
     * @return
     */
    public static byte[] hexToByteArr(String hexStr) {
        int hexlen = hexStr.length();
        byte[] result;
        if (isOdd(hexlen) == 1) {
            // 奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            hexStr = "0" + hexStr;
        } else {
            // 偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(hexStr.substring(i, i + 2));
            j++;
        }
        return result;
    }

    /**
     * int 转 byte[]
     *
     * @param number
     * @return
     */
    public static byte[] intToBytes(int number) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (number >> 24 & 0xFF);
        bytes[1] = (byte) (number >> 16 & 0xFF);
        bytes[2] = (byte) (number >> 8 & 0xFF);
        bytes[3] = (byte) (number & 0xFF);
        return bytes;
    }

    /**
     * byte[] 转 int
     *
     * @param bytes
     * @return
     */
    public static int bytesToInt(byte[] bytes) {
        int num = 0;
        if (bytes != null) {
            int length = bytes.length;
            if (length >= 4) {
                num = bytes[3] & 0xFF;
                num |= ((bytes[2] & 0xFF) << 8);
                num |= ((bytes[1] & 0xFF) << 16);
                num |= ((bytes[0] & 0xFF)<< 24);
            } else if (length == 3) {
                num = bytes[2] & 0xFF;
                num |= ((bytes[1] & 0xFF) << 8);
                num |= ((bytes[0] & 0xFF) << 16);
            } else if (length == 2) {
                num = bytes[1] & 0xFF;
                num |= ((bytes[0] & 0xFF) << 8);
            } else if (length == 1) {
                num = bytes[0] & 0xFF;
            }
        }
        return num;
    }

    /**
     * Byte转Bit
     */
    public static String byteToBit(byte b) {
        return "" + (byte) ((b >> 7) & 0x1) +
                (byte) ((b >> 6) & 0x1) +
                (byte) ((b >> 5) & 0x1) +
                (byte) ((b >> 4) & 0x1) +
                (byte) ((b >> 3) & 0x1) +
                (byte) ((b >> 2) & 0x1) +
                (byte) ((b >> 1) & 0x1) +
                (byte) ((b >> 0) & 0x1);
    }

    /**
     * Bit转Byte
     */
    public static byte bitToByte(String byteStr) {
        int re, len;
        if (null == byteStr) {
            return 0;
        }
        len = byteStr.length();
        if (len != 4 && len != 8) {
            return 0;
        }
        if (len == 8) {
            // 8 bit处理
            if (byteStr.charAt(0) == '0') {
                // 正数
                re = Integer.parseInt(byteStr, 2);
            } else {
                // 负数
                re = Integer.parseInt(byteStr, 2) - 256;
            }
        } else {
            // 4 bit处理
            re = Integer.parseInt(byteStr, 2);
        }
        return (byte) re;
    }
}
